/*
 * Copyright (C) 2010-2011 Comcast Cable.  All Rights Reserved.
 */
package com.hercules.android.receiver.connection.parser.json.itemparsers;

import com.google.gjson.JSONException;
import com.google.gjson.JSONObject;
import com.hercules.android.receiver.connection.parser.CommandParsingException;
import com.hercules.android.receiver.connection.parser.MalformedCommandException;

/**
 * Parser for Object properties.
 * <p>
 * AndroidAssembly2 this class was added in Android Assembly 2
 *
 * @author 7realm
 * @version 1.0
 */
public class ObjectParser extends FieldParser {
    /** Represents object type of property. */
    private final Class<?> objectType;

    /**
     * Constructor for {@link ObjectParser}.
     *
     * @param required if property is required
     * @param objectType the object type of property
     */
    public ObjectParser(boolean required, Class<?> objectType) {
        super(required);
        this.objectType = objectType;
    }

    /**
     * Parses Object property.
     *
     * @param path the path to value
     * @param json the JSON
     * @param keyName the name of current JSON key
     * @param instance the instance of object, parsed value will be set to it
     * @return the parsed value
     * @throws CommandParsingException if error occurs while parsing
     */
    @Override
    protected Object doParse(StringBuilder path, JSONObject json, String keyName, Object instance)
        throws CommandParsingException {
        try {
        	JSONObject innerObject = json.get(keyName).isObject();
            // process case of null value
            if (innerObject == null || innerObject.isNull() != null) {
                return null;
            }

            // because object is expected to be plain POJO we can use newInstance here
            Object object = objectType.newInstance();

            // parse map
            parseMap(path, innerObject, object, SetterType.FIELD);

            return object;
        } catch (IllegalAccessException e) {
            throw new CommandParsingException("Default constructor of command is not accessible. JSON '" + json + "'.",
                e);
        } catch (InstantiationException e) {
            throw new CommandParsingException("Failed to create command using default constructor. JSON '" + json
                + "'.", e);
        } catch (JSONException e) {
            throw new MalformedCommandException("Expected JSONObject at '" + path + "'. JSON '" + json
                + "'.", e);
        }
    }
}
